<?php
namespace App\Http\Controllers\Api\Product;

use App\Http\Requests\ImageRequest;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Model\Product\Product as Model;
use Illuminate\Support\Facades\Storage;

class Product extends Controller
{

    /**商品列表  注意 eolinker  Post 请求请使用： content-Type=application/json  请求体：JSON类型
     * @param Request $req
     * @return array|string
     */
    public function search(Request $req)
    {
        $qry  = Model::query();
        $qry->select('name','mfn','cat', 'mat', 'clr', 'cover', 'user_id');

        if ($req->mfn) {
            $qry->where('mfn', $req->mfn);
        }
        $qry->orderBy('id', 'desc');
        $res = $qry->paginate((int)($req->get('num_per_page') ?: 20));

        $list = json_decode(json_encode($res->items()), 1);
        $user = User::whereIn('id',  array_column($list, 'user_id'))->pluck('name','id')->toArray();

        foreach ($res->items() as $v) {
            $v->user_name = @$user[$v->user_id];
        }

        return $this->resSuccess(
            '商品列表成功。',
            $res
        );
    }

    /**
     * 单元测试用
     * @param $i
     * @return mixed
     */
    public function sum($i) {
        return $i;
    }

    /**
     * 商品详情
     * @param $mfn string
     * @return object
     * */
    public function detail (Request $req)
    {

//        $product = Model::find($req->get('mfn'));
        $product = Model::findWithCache($req->get('mfn'));

        if (!$product) {
            return self::resFail('商品不存在。');
        }


        return $this->resSuccess(
            '商品资料获取成功。',
            array_merge($product->toArray(), [
                'ext' => self::formatProductExtAttributeToEdit($product)
            ])
        );
    }


    /**
     * 保存商品基本信息
     * @param $_id string 商品id，为空表示新增商品
     * @param $mfn string 仅限新增时使用
     * @param $name string 品名
     * @param $cat string 品类
     * @param $clr string 主色
     * @param $mat string 主材质
     * @param $inner_material string 填充材质
     * @param $length float 长
     * @param $width float 长
     * @param $height float 长
     * @param $weight float 长
     * @param $album float 长
     * @return object
     */
    public function save (Request $req)
    {

        // 修改商品信息
        if ($req->post('_id')&&$id=$req->post('mfn')) {

            $product = Model::find($id);
            if (!$product) {
                return self::resFailOfNoData('商品', $id);
            }
        } else {  //create
            $product = new Model();
            $product->user_id = @$req->user()->id ?: 0; //操作人
        }

        // 填充数据
        $product->fill($req->post('_id') ? $req->except('mfn') : $req->all());
        if (!$product->isValid()) {
            return self::resFail($product->debug());
        }
        $product->save();

//        do {
//            try {
//                $error = 0;
//                $product->save();
//            } catch (\Exception $e) {
//                $error = $e->getCode();
//            }
//        } while ($error==11000);
        $product->_id = $product->_id ?: $product->mfn;
        return self::resSuccess('产品基础信息保存成功。', $product);
    }


    /**
     * 导出商品信息
     */
    public function export(Request $req)
    {
        if (!$req->mfn) {
            $obj = Model::get()->toArray();
        } else {
            $mfns = explode(',', $req->mfn);
            foreach ($mfns as $i=>&$mfn) {
                $mfn = trim($mfn);
                if (!$mfn) {
                    unset ($mfns[$i]);
                }
            }
            $obj = Model::find($mfns)->toArray();
        }

        $productInfoTpl = [
            'mfn' => 'mfn',
            'name' => '品名',
            'cat' => '品类',
            'clr' => '主色',
            'mat' => '主材质',
            'length' => '长(CM)',
            'width' => '宽(CM)',
            'height' => '高(CM)',
            'weight' => '重量(KG)',
            'album' => '相册',
        ];

        $tpl = array_merge($productInfoTpl, self::attributeTpl());
//        return $tpl;

        $header = array_keys($tpl);

        $dat = [];
        foreach($obj as $i=> $v) {
            if (@$v['album']) {
                $v['album'] = self::setAlbum($v['album']);
//                $v['album'] = implode(',', $v['album']);
            }
            foreach($header as $k) {
                $dat[$i][] = $this->getNestedVar($v, $k);
            }
        }
//        $excel = new \App\Services\Excel\DownloadArray([
//            $header,
//            $dat
//        ]);

        array_unshift($dat, $header);
//        return $dat;

        return $this->resExcel($dat, 'mfn-product-export.xlsx');

    }


    /**
     * 设置相册数据
     * @param $dat mixed 如果传入数组返回字符串，如果传入字符串则返回数组
     * */
    protected static function setAlbum ($dat)
    {
        return is_array($dat) ? join(',', $dat) : explode(',', $dat);
    }


    //点语法获取数组元素
    private function getNestedVar(&$context, $name) {
        $pieces = explode('.', $name);
        foreach ($pieces as $piece) {
            if (!is_array($context) || !array_key_exists($piece, $context)) {
                // error occurred
                return null;
            }
            $context = &$context[$piece];
        }
        return $context;
    }

    /**
     * 产品扩展属性模板
     * @return array 一维数组：key表示字段名，val是对应的中文名
     * */
    protected static function attributeTpl ()
    {
        $tpl = [];
        $qry = attributeOfProduct(false);

        foreach ($qry as $attr) {
            $tpl = array_merge($tpl, $attr->toExcelArray());
        }
        return $tpl;
    }


    /**
     * 保存扩展属性，无预设的属性将被忽略
     * @param $mfn string 商品MFN
     * @param $ext array 扩展属性组，请求格式和“detail”接口返回值中的ext完全一致
     * @param $ext[].id string 属性id
     * @param $ext[].dat array 属性数据组合
     * @param $ext[].dat[].id string 子属性id
     * @param $ext[].dat[].dat string 子属性值
     * */
    public function saveAttribute (Request $req)
    {
        $product = Model::find($req->post('mfn'));

        if (!$product) {
            return self::resFail('商品不存在。');
        }

        $req = $req->post('ext');
        $qry = attributeOfProduct(false);

        foreach ($req as $i=>$post) {
            if (is_int($i)) {
                if (@$post['on']&&$attr=$qry->where('id', @$post['id'])->first()) {
                    // 数据库中的参数
                    $req[$post['id']] = $attr->toProductJson($post['sub'], false);
                }
                unset ($req[$i]);
            }
        }

        $product->forceFill($req)->save();

        return self::resSuccess('产品属性保存成功。');

    }


    /** 上传图片到本地服务器
     *  @param  photo file
     * @return imgUrl string
     */
    public function uploadImgLocal(Request $req)
    {
        if (! $file = $req->file('photo')) {
            return $this->resFail('请上传图片');
        }

//        $path = $req->photo->path();
//        $extension = $req->photo->extension();

        //上传文件到 /storage/app/public
        //php artisan storage:link
        $res =  $file->store('product/images','public'); //public： filesystem 配置项

        return $this->resSuccess('上传成功',  'storage/'.$res );

    }


    /**
     * 上传图片到云存储 (又拍云)
     * @param file $image
     */
    public function uploadImgUpyun(ImageRequest $request){
        $imageUrl = Storage::disk('upyun')->put('/product', $request->file('image'));

        return $this->resSuccess('操作成功', $imageUrl );
    }









    /**
     * 转化商品扩展属性为编辑格式
     * @param $product object 商品Model
     * @return array
     * */
    protected static function formatProductExtAttributeToEdit (Model $product)
    {
        $qry = attributeOfProduct()->toArray();
        \Log::info($qry);


        foreach ($qry as &$group) {
            if ($attr=$product->{$group['id']}) {
                foreach ($product->{$group['id']} as $key=>$val) {
                    $group['sub'] = array_combine(
                        array_column($group['sub'], 'id'),
                        $group['sub']
                    );
                    // 将产品属性赋值给$attr
                    if (@$group['sub'][$key]) {
                        $group['sub'][$key]['dat'] = $val;
                    }
                }
            }
            $group['on'] = (bool)$product->{$group['id']};
            $group['sub'] = array_values($group['sub']);
        }


        return $qry;

    }

}